package com.noahplat.person.service.impl;

import com.noahplat.common.cusexception.RedisException;
import com.noahplat.common.utils.NoahEnum;
import com.noahplat.common.utils.RedisUtils;
import com.noahplat.common.utils.Result;
import com.noahplat.common.utils.StatusCode;
import com.noahplat.device.feign.DeviceFeign;
import com.noahplat.device.pojo.Device;
import com.noahplat.person.mapper.PersonDeviceMapper;
import com.noahplat.person.pojo.PersonDevice;
import com.noahplat.person.service.PersonDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/**
 * @ClassName: PersonDeviceServiceImpl
 * @Description: 人员设备绑定关系实现类
 * @Author 李景星
 * @Date 2021/3/9
 * @Version 1.0
 */
@Service
public class PersonDeviceServiceImpl implements PersonDeviceService {

    @Autowired
    private PersonDeviceMapper personDeviceMapper;
    @Autowired
    private DeviceFeign deviceFeign;
    @Autowired
    private RedisUtils redisUtils;

    /**
     * 添加人员设备绑定关系
     * @param imei
     * @param devcode
     * @param pid
     * @return
     */
    @Transactional
    @Override
    public Result addPersonDevice(String imei, String devcode, Long pid,String registrationid,String devtype) {
        //调用远程微服务获取设备详细信息
        Result<Device> device = deviceFeign.getDevice(imei);
        if(ObjectUtils.isEmpty(device)){
            return new Result(false, StatusCode.ERROR, "绑定设备不存在");
        }
        //对比设备校验码，若校验码正确，新增绑定关系，反之不允许绑定
        if(!devcode.equals(device.getData().getDevcode())){
            return new Result(false, StatusCode.ERROR, "设备激活码错误");
        }

        Example example1 = new Example(PersonDevice.class);
        example1.createCriteria().andEqualTo("pid",pid).andEqualTo("imei",imei);
        PersonDevice personDevice1 = personDeviceMapper.selectOneByExample(example1);
        if(!ObjectUtils.isEmpty(personDevice1)){
            return new Result(false,StatusCode.ERROR,"已绑定该设备");
        }
        PersonDevice personDevice = new PersonDevice();
        personDevice.setPid(pid);
        personDevice.setImei(imei);
        personDevice.setModel(device.getData().getModel());
        personDevice.setType(device.getData().getType());
        personDevice.setSupLocation(device.getData().getSupLocation());
        personDevice.setSupTemp(device.getData().getSupTemp());
        personDevice.setSupHeart(device.getData().getSupHeart());
        personDevice.setSupBlood(device.getData().getSupBlood());
        personDevice.setSupSleep(device.getData().getSupSleep());
        personDevice.setSupStep(device.getData().getSupStep());
        personDevice.setSupOxygen(device.getData().getSupOxygen());
        personDevice.setCreateTime(new Date());
        personDevice.setRegistrationid(registrationid);
        personDevice.setDevType(devtype);
        personDevice.setImage(device.getData().getImage());
        //判断是否有默认设备
        Example example = new Example(PersonDevice.class);
        example.createCriteria().andEqualTo("pid", pid).andEqualTo("defaultFlag", "Y");
        PersonDevice res = personDeviceMapper.selectOneByExample(example);
        if(ObjectUtils.isEmpty(res)){
            personDevice.setDefaultFlag("Y");
        }else {
            personDevice.setDefaultFlag("N");
        }

        int insertRes = personDeviceMapper.insert(personDevice);
        if(insertRes > 0){
            boolean redisres = redisUtils.lSet(NoahEnum.JPUSHDIR.getCode()+imei,personDevice);
            if(!redisres){
                throw new RedisException();
            }
            return new Result(true, StatusCode.OK, "绑定成功");
        }
        return new Result(false, StatusCode.ERROR, "绑定失败");
    }

    /**
     * 获取人员设备绑定关系
     * @param pid
     * @return
     */
    @Override
    public Result getPersonDevice(Long pid) {
        Example example = new Example(PersonDevice.class);
        example.createCriteria().andEqualTo("pid", pid);
        List<PersonDevice> personDevices = personDeviceMapper.selectByExample(example);
        if(ObjectUtils.isEmpty(personDevices)){
            return new Result(true, StatusCode.OK, "当前暂无绑定设备", personDevices);
        }
        return new Result(true, StatusCode.OK, "查询成功", personDevices);
    }

    /**
     * 解除人员绑定关系
     * @param id
     * @return
     */
    @Transactional
    @Override
    public Result delPersonDevice(Long id) {
        //先查询该设备是否为默认设备
        PersonDevice personDevice = personDeviceMapper.selectByPrimaryKey(id);
        if(ObjectUtils.isEmpty(personDevice)){
           return new Result(false, StatusCode.ERROR, "未绑定该设备");
        }
        //直接删除
        int delRes = personDeviceMapper.deleteByPrimaryKey(id);
        if(delRes > 0){
            if(personDevice.getDefaultFlag().equals("Y")){//默认设备
                PersonDevice onePersonDevice = personDeviceMapper.getOne(personDevice.getPid());
                boolean selectres = redisUtils.hasKey(NoahEnum.JPUSHDIR.getCode()+personDevice.getImei());
                if(!selectres){
                    Result inres = inRedis(personDevice.getImei());
                    if(!inres.isFlag()){
                        return new Result(false, StatusCode.ERROR, "更新失败");
                    }
                }
                List<Object> list = redisUtils.lGet(NoahEnum.JPUSHDIR.getCode()+personDevice.getImei(),0,-1);
                if(ObjectUtils.isEmpty(list)){
                    throw new RedisException();
                }
                for(Object object : list){
                    PersonDevice personDevice1 = (PersonDevice) object;
                    if(personDevice.getId().equals(personDevice1.getId())){
                        Long res = redisUtils.lRemove(NoahEnum.JPUSHDIR.getCode()+personDevice.getImei(),1,object);
                        if(res == 0){
                            throw new RedisException();
                        }
                        break;
                    }
                }

                if(ObjectUtils.isEmpty(onePersonDevice)){//只有一台设备的情况
                    return new Result(true, StatusCode.OK, "删除成功");
                }
                onePersonDevice.setDefaultFlag("Y");
                personDeviceMapper.updateByPrimaryKeySelective(onePersonDevice);
                for(Object object1 : list){
                    PersonDevice personDevice1 = (PersonDevice) object1;
                    if(onePersonDevice.getId().equals(personDevice1.getId())){
                        Long res = redisUtils.lRemove(NoahEnum.JPUSHDIR.getCode()+personDevice.getImei(),1,object1);
                        if(res == 0){
                            throw new RedisException();
                        }
                        boolean redisres = redisUtils.lSet(NoahEnum.JPUSHDIR.getCode()+onePersonDevice.getImei(),onePersonDevice);
                        if(!redisres){
                            throw new RedisException();
                        }
                        break;
                    }
                }

                return new Result(true, StatusCode.OK, "删除成功");
            }
        }

        return new Result(false, StatusCode.ERROR, "删除失败");
    }

    /**
     * 更新人员设备绑定关系
     * @param personDevice
     * @return
     */
    @Transactional
    @Override
    public Result updatePersonDevice(PersonDevice personDevice) {
        //旧设备变更为非默认设备
        Example example = new Example(PersonDevice.class);
        example.createCriteria().andEqualTo("pid", personDevice.getPid()).andEqualTo("defaultFlag", "Y");
        PersonDevice oldPersonDevice = personDeviceMapper.selectOneByExample(example);
        oldPersonDevice.setDefaultFlag("N");
        int oldRes = personDeviceMapper.updateByPrimaryKeySelective(oldPersonDevice);
        //新设备变更为为默认设备
        int newRes = personDeviceMapper.updateByPrimaryKeySelective(personDevice);

        if(oldRes > 0 && newRes > 0){
            boolean res = redisUtils.hasKey(NoahEnum.JPUSHDIR.getCode()+personDevice.getImei());
            if(!res){
                Result inres = inRedis(personDevice.getImei());
                if(!inres.isFlag()){
                    return new Result(false, StatusCode.ERROR, "更新失败");
                }
            }
            Result playres = playRedis(personDevice);
            if(!playres.isFlag()){
                return new Result(false, StatusCode.ERROR, "更新失败");
            }

            boolean oldres = redisUtils.hasKey(NoahEnum.JPUSHDIR.getCode()+oldPersonDevice.getImei());
            if(!oldres){
                Result inres = inRedis(oldPersonDevice.getImei());
                if(!inres.isFlag()){
                    return new Result(false, StatusCode.ERROR, "更新失败");
                }
            }

            Result playoldres = playRedis(oldPersonDevice);
            if(!playoldres.isFlag()){
                return new Result(false, StatusCode.ERROR, "更新失败");
            }

            return new Result(true, StatusCode.OK, "更新成功");
        }
        return new Result(false, StatusCode.ERROR, "更新失败");
    }


    /**
     * 设备和手机绑定关系检验
     * @param pid
     * @param registrationid
     * @param devtype
     * @return
     */
    @Transactional
    @Override
    public Result updateRegis( Long pid, String registrationid, String devtype){
        Example example = new Example(PersonDevice.class);
        example.createCriteria().andEqualTo("pid",pid);
        List<PersonDevice> list = personDeviceMapper.selectByExample(example);
        if(ObjectUtils.isEmpty(list)){
            return new Result(false,StatusCode.ERROR,"修改绑定关系失败");
        }
        for (PersonDevice personDevice : list){
            if (registrationid.equals(personDevice.getRegistrationid())){
                return new Result(true,StatusCode.OK,"修改绑定关系成功");
            }
            break;
        }
        PersonDevice personDevice = new PersonDevice();
        personDevice.setRegistrationid(registrationid);
        personDevice.setDevType(devtype);
        int res = personDeviceMapper.updateByExampleSelective(personDevice,example);
        if(res == 0){
            return new Result(false,StatusCode.ERROR,"修改绑定关系失败");
        }
        for(PersonDevice personDevice1 : list){
            boolean selectres = redisUtils.hasKey(NoahEnum.JPUSHDIR.getCode()+personDevice1.getImei());
            if(!selectres){
                Result inres = inRedis(personDevice.getImei());
                if(!inres.isFlag()){
                    return new Result(false, StatusCode.ERROR, "修改绑定关系失败");
                }
            }
            personDevice1.setRegistrationid(registrationid);
            personDevice1.setDevType(devtype);
            Result playres = playRedis(personDevice1);
            if(!playres.isFlag()){
                return new Result(false, StatusCode.ERROR, "修改绑定关系失败");
            }
        }
        return new Result(true,StatusCode.OK,"修改绑定关系成功成功");
    }

    /**
     * 获取默认设备
     * @param pid
     * @return
     */
    @Override
    public Result getDefaultDevice(Long pid) {
        Example example = new Example(PersonDevice.class);
        example.createCriteria().andEqualTo("pid", pid).andEqualTo("defaultFlag", "Y");
        PersonDevice personDevice = personDeviceMapper.selectOneByExample(example);
        if(ObjectUtils.isEmpty(personDevice)){
            return new Result(true, StatusCode.OK, "暂无默认设备");
        }
        return new Result(true, StatusCode.OK, "查询成功", personDevice);
    }

    /**
     * 修改内存操作方法
     * 宋彦磊
     * @param personDevice
     * @return
     */
    public Result playRedis(PersonDevice personDevice){
        List<Object> list = redisUtils.lGet(NoahEnum.JPUSHDIR.getCode()+personDevice.getImei(),0,-1);
        if(ObjectUtils.isEmpty(list)){
            throw new RedisException();
        }
        for(Object object : list){
            PersonDevice personDevice1 = (PersonDevice) object;
            if(personDevice.getId().equals(personDevice1.getId())){
                Long delres = redisUtils.lRemove(NoahEnum.JPUSHDIR.getCode()+personDevice.getImei(),1,object);
                if(delres == 0){
                    throw new RedisException();
                }
                boolean redisres = redisUtils.lSet(NoahEnum.JPUSHDIR.getCode()+personDevice.getImei(),personDevice);
                if(!redisres){
                    throw new RedisException();
                }
                break;
            }
        }
        return new Result(true,StatusCode.OK,"修改成功");
    }

    /**
     * 查询内存操作方法
     * 宋彦磊
     * @param imei
     * @return
     */
    @Override
    public Result inRedis(String imei){
        Example example1 = new Example(PersonDevice.class);
        example1.createCriteria().andEqualTo("imei",imei);
        List<PersonDevice> list = personDeviceMapper.selectByExample(example1);
        if(ObjectUtils.isEmpty(list)){
            return new Result(false,StatusCode.OK,"修改失败");
        }
        for(PersonDevice personDevice : list){
            boolean intres = redisUtils.lSet(NoahEnum.JPUSHDIR.getCode()+imei,personDevice);
            if(!intres){
                throw new RedisException();
            }
        }

        return new Result(true,StatusCode.OK,"修改成功");
    }
}
